package cn.fintecher.gis.web;


import cn.fintecher.gis.annotation.CurrentOperator;
import cn.fintecher.gis.entity.Layer3D;
import cn.fintecher.gis.exception.BadRequestException;
import cn.fintecher.gis.model.request.Layer3DRequest;
import cn.fintecher.gis.model.response.Layer3DResponse;
import cn.fintecher.gis.model.session.SessionModel;
import cn.fintecher.gis.respository.Layer3DRepository;
import cn.fintecher.gis.respository.OperatorRepository;
import cn.fintecher.gis.service.LogInfoService;
import com.querydsl.core.types.Predicate;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.modelmapper.ModelMapper;
import org.modelmapper.TypeToken;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.binding.QuerydslPredicate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;

/**
 * Created by ChenChang on 2018/12/11.
 */
@RestController
@RequestMapping("/api/layer3D")
@Api(value = "3d图层", description = "3d图层")
public class Layer3DController {
    private final Logger log = LoggerFactory.getLogger(Layer3DController.class);
    @Autowired
    private Layer3DRepository layer3DRepository;

    @Autowired
    private OperatorRepository operatorRepository;

    @Autowired
    private LogInfoService logInfoService;

    @Autowired
    private ModelMapper modelMapper;

    @ApiOperation(value = "按ID查询", notes = "按ID查询")
    @GetMapping("/getLayer3D/{id}")
    public ResponseEntity<Layer3D> getLayer3D(@PathVariable String id) {
        log.debug("REST request to get Layer3D : {}", id);
        Layer3D layer3D = layer3DRepository.findById(id).get();
        Layer3D response = modelMapper.map(layer3D, Layer3D.class);
        return Optional.ofNullable(response)
                .map(result -> new ResponseEntity<>(
                        result,
                        HttpStatus.OK))
                .orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
    }

    @ApiOperation(value = "查询所有", notes = "查询所有")
    @GetMapping("/getAllLayer3Ds")
    public ResponseEntity<List<Layer3D>> getAllLayer3Ds() {
        log.debug("REST request to get all of Layer3D");
        Type listType = new TypeToken<List<Layer3D>>() {
        }.getType();
        List<Layer3D> list = modelMapper.map(layer3DRepository.findAll(), listType);
        return new ResponseEntity<>(list, HttpStatus.OK);
    }

    @ApiOperation(value = "查询", notes = "查询")
    @GetMapping("/query")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", dataType = "int", paramType = "query",
                    value = "页数 (0..N)"),
            @ApiImplicitParam(name = "size", dataType = "int", paramType = "query",
                    value = "每页大小."),
            @ApiImplicitParam(name = "sort", allowMultiple = true, dataType = "string", paramType = "query",
                    value = "依据什么排序: 属性名(,asc|desc). ")
    })
    public ResponseEntity<Page<Layer3DResponse>> query(Pageable pageable, @QuerydslPredicate(root = Layer3D.class) Predicate predicate) {
        log.debug("REST request to query Layer3D");
//        Page<Layer3D> allList = layer3DRepository.findAll(predicate, pageable).dataMap(layer3D -> {
//            Layer3D response = modelMapper.dataMap(layer3D, Layer3D.class);
//            return response;
//        });
        Page<Layer3D> LayerPage = layer3DRepository.findAll(predicate, pageable);
        Iterator<Layer3D> iterator = LayerPage.iterator();
        List<Layer3DResponse> list = new ArrayList<>();
        while (iterator.hasNext()) {
            Layer3D layer3D = iterator.next();
            Layer3DResponse response = new Layer3DResponse();
            BeanUtils.copyProperties(layer3D, response);
            response.setUserId(layer3D.getCreateOperator());
            response.setUserName(layer3D.getCreateName());
            list.add(response);
        }
        Page<Layer3DResponse> allList = new PageImpl<>(list, pageable, LayerPage.getTotalElements());
        return new ResponseEntity<>(allList, HttpStatus.OK);
    }

    @ApiOperation(value = "创建", notes = "创建")
    @PostMapping("/createLayer3D")
    public ResponseEntity<Layer3D> createLayer3D(@RequestBody Layer3DRequest request,
                                                 @CurrentOperator SessionModel sessionModel) throws URISyntaxException {
        log.debug("REST request to save Layer3D : {}", request);

        Layer3D layer3D = new Layer3D();
        BeanUtils.copyProperties(request, layer3D);
        layer3D.setId(null);
        layer3D.setCreateTime(new Date());
        layer3D.setCreateOperator(sessionModel.getId());
        layer3D.setCreateName(sessionModel.getUsername());
        Layer3D result = layer3DRepository.save(layer3D);


        return ResponseEntity.created(new URI("/api/layer3D/" + result.getId()))
                .body(result);
    }

    @ApiOperation(value = "修改", notes = "修改")
    @PutMapping("/updateLayer3D")
    public ResponseEntity<Layer3D> updateLayer3D(@RequestBody Layer3DRequest request) {
        log.debug("REST request to save Layer3D : {}", request);
        if (Objects.isNull(request.getId())) {
            throw new BadRequestException("updateLayer3D", "id.is.null");
        }
        Layer3D layer3D = layer3DRepository.findById(request.getId()).get();
        BeanUtils.copyProperties(request, layer3D);
        Layer3D result = layer3DRepository.save(layer3D);
        Layer3D operatorModel = modelMapper.map(result, Layer3D.class);
        return ResponseEntity.ok()
                .body(operatorModel);
    }


    @ApiOperation(value = "删除", notes = "删除")
    @DeleteMapping("/deleteLayer3D/{id}")
    public ResponseEntity<Void> deleteLayer3D(@PathVariable String id) {
        log.debug("REST request to delete layer3D : {}", id);
        Optional<Layer3D> optional = layer3DRepository.findById(id);
        if (optional.isPresent()) {
            Layer3D layer3D = optional.get();
            logInfoService.addLog("Layer3DController", "deleteLayer3D",
                    "id=" + id, "删除的3D图层名称是:" + layer3D.getName());
            layer3DRepository.delete(layer3D);
        }
        return ResponseEntity.ok().build();
    }
}